﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Timers;

namespace ProcessScheduler
{
    public class ProcessScheduleItem
    {
        Process process;
        public Guid Id { get; set; }
        public string Command { get; set; }
        public string Arguments { get; set; }
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
        Timer timerStart = new Timer();
        Timer timerEnd = new Timer();

        public TimeSpan Duration
        {
            get
            {
                return EndTime - StartTime;
            }
            set
            {
                if (value != null)
                    EndTime = StartTime.Add(value);
                else
                    throw new Exception("Duration can't be null");
            }
        }

        #region Construction
        public ProcessScheduleItem(string command, string arguments, DateTime startTime, DateTime endTime)
        {
            Command = command;
            StartTime = startTime;
            EndTime = endTime;
            Arguments = arguments;
            
            timerStart.Interval = (StartTime - DateTime.Now).TotalMilliseconds;
            timerEnd.Interval = (EndTime - DateTime.Now).TotalMilliseconds;

            timerStart.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timerEnd.Elapsed += new ElapsedEventHandler(timerEnd_Elapsed);
            timerEnd.Start();
            timerStart.Start();
            Id = Guid.NewGuid();
        }

        public ProcessScheduleItem(string command, string arguments, DateTime startTime, TimeSpan duration)
        {
            Command = command;
            StartTime = startTime;
            Duration = duration;
            Arguments = arguments;

            timerStart.Interval = (StartTime - DateTime.Now).TotalMilliseconds;
            timerEnd.Interval = (EndTime - DateTime.Now).TotalMilliseconds;

            timerStart.Elapsed += new ElapsedEventHandler(timer_Elapsed);
            timerEnd.Elapsed += new ElapsedEventHandler(timerEnd_Elapsed);
            Id = Guid.NewGuid();
        }
        #endregion

        #region Events
        void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            process = new Process();
            ProcessStartInfo startInfo = new ProcessStartInfo(Command, Arguments);
            startInfo.WindowStyle = ProcessWindowStyle.Hidden;

            process.StartInfo = startInfo;
            
            process.Start();
            timerStart.Close();
        }
        void timerEnd_Elapsed(object sender, ElapsedEventArgs e)
        {
            CloseProcess();
            process.Close();
            process = null;
            timerEnd.Close();
        } 
        #endregion Events

        #region Methods
        public bool CanStop
        {
            get
            {
                return process == null;
            }
        }

        private void CloseProcess()
        {
            bool closed = process.CloseMainWindow();
            if (!closed)
                process.Kill();
        }

        public void ForceToStop()
        {
            if (!CanStop)
            {
                CloseProcess();
                process.Close();
                process = null;
                timerEnd.Close();
                //return closed;
            }
        }
        #endregion Methods
    }
}
